<?php

/**
 * @version    $Id: loader.php 1 2016-07-19 08:45:53Z tic $
 */
define("IN_SYS", true);

define('DS', DIRECTORY_SEPARATOR);
define("CORE", dirname(__FILE__));
define("ROOT", dirname(CORE));
define("DATA", ROOT . DS . "data");
define('TIMESTAMP', time());
define('REMOTEAPI', "http://api.yumingcms.com");
//define('REMOTEAPI', "http://ymcms_api.140ed8.com");

@include DATA . DS . 'config.php';
@include CORE . DS . 'functions.php';

if (empty($auth_key)) {
    echo '<script>window.location.href="install.php";</script>';
    exit;
}

set_exception_handler(array('loader', 'exception_handler'));
set_error_handler(array('loader', 'exception_error_handler'));
register_shutdown_function(array('loader', 'exception_shutdown_handler'));
if ($debug == true) {
    ini_set('display_errors', '1');
    error_reporting(E_ALL);
} else {
    error_reporting(0);
}

date_default_timezone_set('PRC');
set_include_path(CORE . PATH_SEPARATOR . get_include_path());
session_save_path(DATA . DS . 'session');
@ini_set('memory_limit', '64M');
@ini_set('session.cache_expire', 180);
@ini_set('session.use_trans_sid', 0);
@ini_set('session.use_cookies', 1);
@ini_set('session.auto_start', 0);

header("Content-type: text/html; charset=utf-8");
if (version_compare(PHP_VERSION, '5.2.0', '<'))
    throw new Exception("Worning: PHP VERSION NOT SUPPORT!", 0);
define("IS_POST", isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST' || gp('callback') != '');
define("IS_AJAX", isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');

foreach (array('_POST', '_GET', '_COOKIE', '_REQUEST') as $_method) {
    if (!defined('NOFILTER')) {
        $$_method = filter::xss($$_method);
    }
    $$_method = filter::input($$_method);
}

class loader {

    public static $error = array();

    /*
     * Init 开始
     */

    public static function init() {
        $loader = new loader();
        $loader->environment();
        $loader->router();
        return $loader;
    }

    /*
     * 加载模块
     */

    public function load($extension) {
        $this->{'load_' . $extension}();
        return $this;
    }

    /*
     * 运行项目
     */

    public function cli_run() {
        if (PHP_SAPI !== 'cli') {  //只允许命令行模式
            exit('非法访问');
        }
        $argv = $_SERVER['argv'];
        if (!is_array($argv) || count($argv) <= 0) {
            exit("无效的参数");
        }
        $param = $argv;
        $controller = $argv[1];
        $method = $argv[2];
        $file = ROOT . '/crontab/' . $controller . '.php';

        if (is_file($file)) {
            require $file;
            $object = new $controller();
            if (method_exists($object, $method)) {
                call_user_func(array($object, $method), $param);
            } else {
                exit("无效的方法");
            }
        } else {
            exit("无效的命令");
        }
    }

    /*
     * 运行项目
     */

    public function run() {
        $m = M;
        if(check_routes($m)==true) {
            $file = ROOT . '/control/jschong.php';
            $m = 'jschong';
        }elseif (defined('APPNAME')) {
            $file = ROOT . '/' . APPNAME . '/control/' . $m . '.php';
        } else {
            $file = ROOT . '/control/' . $m . '.php';
        }
        
        if (!is_file($file) && !defined('APPNAME')) {
            if (is_dir(ROOT . DS . $m)) {
                controller::page_404();
                exit;
            }
            $m = 'index';
            $file = ROOT . '/control/index.php';
        }

        if (is_file($file)) {
            require $file;
            $m = $m . '_controller';
            $object = new $m();
            if (method_exists($object, A)) {
                call_user_func(array($object, A));
            } elseif (method_exists($object, '_empty')) {
                call_user_func(array($object, '_empty'), A);
            } else {
                controller::page_404();
                exit;
            }
        } else {
            controller::page_404();
            exit;
        }
    }

    /*
     * 环境变量处理
     */

    public function environment() {

        if (!isset($_SERVER['REQUEST_URI'])) {
            if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) {
                $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_ORIGINAL_URL'];
            } else {
                $_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING'];
            }
        }
        $_SERVER['REQUEST_URI'] = str_replace('/index.php', '', $_SERVER['REQUEST_URI']);
        $temp = strtoupper(urldecode(urldecode($_SERVER['REQUEST_URI'])));
        if (strpos($temp, '<') !== false || strpos($temp, '"') !== false || strpos($temp, "'") !== false || strpos($temp, "*") !== false || strpos($temp, 'CONTENT-TRANSFER-ENCODING') !== false) {
            controller::page_404();
        }
    }

    /*
     * 路由
     */

    public function router() {
        if ($request_uri_fixed = trim(preg_replace('#\?.*$#', '', $_SERVER['REQUEST_URI']), '/')) {
            $request_uri_variable = explode('/', $request_uri_fixed);
            foreach ($request_uri_variable as $key => $value) {
                $value = str_replace('.html', '', $value);
                $value = str_replace('.php', '', $value);
                if (defined('APPNAME')) {
                    $keyidx = $key - 1;
                } else {
                    $keyidx = $key;
                }
                if ($keyidx == 0) {
                    $_GET['m'] = $value;
                } elseif ($keyidx == 1) {
                    $_GET['a'] = $value;
                } elseif ($keyidx >= 2 && $keyidx % 2 == 0 && isset($request_uri_variable[$keyidx + 1]) && preg_match('#^[a-z0-9_]*$#', $value)) {
                    $_GET[$value] = $_REQUEST[$value] = $request_uri_variable[$keyidx + 1];
                }
            }
        }
        if (preg_match("#hotnews-(.*)(\.html)?#", $_GET['m'], $mt)) {
            define('M', hotnews);
            if(!empty($mt[1])) {
                $ms= explode('-',$mt[1]);
                define('A', urldecode($ms[0]));
            }
            
        }else {
            $m = !empty($_GET['m']) ? preg_replace('#[^a-z0-9_]#i', '', $_GET['m']) : 'index';
            define('CAT', $m);
            define('M', $m);

            $a = !empty($_GET['a']) ? preg_replace('#[^a-z0-9_]#i', '', $_GET['a']) : 'index';
            $acts = array('news', 'hot', 'tu', 'sitemapxml'); 
            if (in_array($a, $acts)) {
                define('A', 'index');
            } else {
                define('A', $a);
            }
        }
        
    }

    /*
     * session模块
     */

    public function load_session() {
        return new session();
    }

    /*
     * 异常处理
     */

    public static function exception_handler($exception) {
        $errstr = $exception->getMessage();
        $errfile = $exception->getFile();
        $errline = $exception->getLine();
        self::exception_error_handler(0, $errstr, $errfile, $errline);
    }

    /*
     * 异常处理
     */

    public static function exception_shutdown_handler() {
        if (($error = error_get_last())) {
            self::exception_error_handler($error['type'], $error['message'], $error['file'], $error['line']);
        }
        if (self::$error) {
            self::$error = join("<br/>", self::$error);
            self::show_error(self::$error);
        }
    }

    /*
     * 异常处理
     */

    public static function exception_error_handler($errno, $errstr, $errfile, $errline) {
        global $debug;
        global $error_log;
        $errfile = str_replace("\\", '/', str_replace(ROOT, '', $errfile));
        $errortype = array(0 => 'Exception', 1 => 'Fatal error', 2 => 'Warning', 4 => 'Parsing Error', 8 => 'Notice', 16 => 'Core Error', 32 => 'Core Warning', 64 => 'Compile Error', 128 => 'Compile Warning', 256 => 'User Error', 512 => 'User Warning', 1024 => 'User Notice', 2048 => 'Runtime Notice', 4096 => 'Recoverable Error');
        $error_message = $errortype[$errno] . ' | ' . str_pad($errstr, 50) . ' | ' . $errfile . ' | ' . $errline . ' | ' . get_url();
        if ($error_log == true) {
            error_log('<?php exit;?>' . date('m-d H:i:s') . ' | ' . $error_message . "\r\n", 3, DATA . '/log/errorlog_' . date("Y-m-d") . '.php');
        }
        if ($debug == true) {
            self::$error[] = $errno ? "<b>{$errortype[$errno]}</b>: $errstr in <b>$errfile</b> on line <b>$errline</b>" : $errstr;
        } else {
            if (in_array($errno, array(0, E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR))) {
                controller::page_503();
                self::$error[] = $errno ? "系统发生" . $errortype[$errno] . "错误" : $errstr;
            }
        }
    }

    /*
     * 异常输出
     */

    public static function show_error($message) {
        global $debug;
        $debug_bar_color = $debug ? "#E6A43F" : '#EEE';
        echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
        echo "<h1>System Error!</h1><div style='position:relative;border:solid 1px #CCC;padding:10px;margin-bottom:28px;background-color:#F6F6F6;font-size:12px;z-index:9999;'>$message</div>";
        echo "<p style='position:fixed;bottom:0px;left:0px;width:100%;background-color:{$debug_bar_color};border-top:solid 1px #0094df;padding:5px;z-index:9999;'><font color=#666 size=1>系统已记录此错误, 由此给您带来不便我们深感歉意.</font></p>";
    }

}
